package com.example.idol;

import java.util.Date;
import java.util.List;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * define IDOL model classes
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class IDOL {
    // API defines two parameters(text,json) for text type input, but it can be one.
    public enum InputSource {text, json, file, reference, url}
    public enum DuplicateMode {replace, duplicate}
    
    // define IDOL Error response
    public static class ErrorResponse {
        public Integer error;       // error code
        public String reason;       // error reason
        //public Detail> detail;
        public String jobID;        // job ID
        public String status;       // job status
        //public Action actions;        // failed action list
    }
    
    // index flavor enumeration
    public enum IndexFlavor {standard}
    
    // define IDOL Index
    public static class Index {
        public String index;
        public String type;
        public String flavor;
        public String description;
        public String date_created;
        public Integer num_components;
    }
    
    // define IDOL public index
    public static class PublicIndex {
        public String index;
        public String type;
    }
    
    // define list indexes response
    public static class ListIndexesResponse {
        public List<IDOL.Index> index;               // custom indexes
        public List<IDOL.PublicIndex> public_index; // default indexes
    }
    
    // define create text index response
    public static class CreateTextIndexResponse {
        public String message;  // optional
        public String index;    // optional
    }
    
    public static class AddToTextIndexResponse {
        public String index;            // optional
        public List<IDOL.References> references;    // optional
    }
    
    public static class References {
        public Integer id;  // not in the API doc, but response returns id
        public String reference;
    }

    // define delte text index response 
    public static class DeleteTextIndexResponse {
        public Boolean deleted;
        public String index;    // optional
        public String confirm;  // optional
    }

    // define delete from text index response
    public static class DeleteFromTextIndexResponse {
        public String index;
        public Integer documents_deleted;
    }
    
    // define index status
    // 24hr_index_updates starts with number, so it can't be used for deserialization. It would better if it starts with non-digit.
    // instead use Map<String, Object> m = (Map<String, Object>)JSON.deserializeUntyped(jsonInput);
    public static class IndexStatusResponse {
        public Integer total_documents;
        public Integer total_index_size;
        @JsonProperty(value="24hr_index_updates")
        public Integer hr24_index_updates;  // original property name is 24hr_index_updates
    }
    
    // Language list in LanguageIdentificationResponse
    public enum Language {afrikaans, albanian, amharic, arabic, armenian, azeri, basque, belarussian, bengali, berber, breton, bulgarian, burmese, catalan, cherokee, chinese, croatian, czech, danish, dutch, english, esperanto, estonian, faroese, finnish, french, gaelic, georgian, german, greek, greenlandic, gujarati, hebrew, hindi, hungarian, icelandic, indonesian, italian, japanese, kannada, kazakh, khmer, korean, kurdish, lao, latin, latvian, lithuanian, luxembourgish, macedonian, malayalam, maltese, maori, mongolian, nepali, norwegian, oriya, persian, polish, portuguese, pushto, romanian, russian, serbian, sindhi, singhalese, slovak, slovenian, somali, spanish, swahili, swedish, syriac, tagalog, tajik, tamil, telugu, thai, tibetan, turkish, ukrainian, urdu, uyghur, uzbek, vietnamese, welsh, unknown }
    public enum LanguageIso639_2b {AFR, ALB, AMH, ARA, ARM, AZE, BAQ, BEL, BEN, BER, BRE, BUL, BUR, CAT, CHR, CHI, HRV, CZE, DAN, DUT, ENG, EPO, EST, FAO, FIN, FRE, GLE, GEO, GER, GRE, KAL, GUJ, HEB, HIN, HUN, ICE, IND, ITA, JPN, KAN, KAZ, KHM, KOR, KUR, LAO, LAT, LAV, LIT, LTZ, MAC, MAL, MLT, MAO, MON, NEP, NPI, NOR, ORI, PER, POL, POR, PUS, RUM, RUS, SRP, SND, SIN, SLO, SLV, SOM, SPA, SWA, SWE, SYR, TGL, TGK, TAM, TEL, THA, TIB, TUR, UKR, URD, UIG, UZB, VIE, WEL, UND}
    // Encoding list in LanguageIdentificationResponse
    public enum Encoding {ARABIC, ARABIC_ISO, ASCII, CHINESESIMPLIFIED, CHINESETRADITIONAL, CYRILLIC, CYRILLIC_ISO, CYRILLIC_KOI8, EASTERNEUROPEAN, EASTERNEUROPEAN_ISO, EUC, GREEK, GREEK_ISO, HEBREW, HEBREW_ISO, JIS, KOREAN, NORTHERNEUROPEAN, NORTHERNEUROPEAN_ISO, SHIFTJIS, THAI, TURKISH, UTF8, VIETNAMESE}

    // define language identification response
    public static class LanguageIdentificationResponse {
        // JSON deserialization doesn't work with enum type, so need to use String
        public String language;
        public String language_iso639_2b;
        public String encoding;
        public List<String> unicode_scripts;
    }
    
    // Sentiment enumaration in SentimentAnalysisResponse.Aggregate
    public enum Sentiment {positive, negative, neutral}
    // Three-char language code used in SentimentAnalysis request
    public enum LanguageCode {eng, fre, spa, ger, ita, chi}
    
    // define sentiment analysis response
    public static class SentimentAnalysisResponse {
        public List<IDOL.Entity> positive;
        public List<IDOL.Entity> negative;
        public IDOL.Aggregate aggregate;
    }
    
    // define entity in SentimentAnalysisResponse
    public static class Entity {
        public String sentiment;
        public String topic;
        public Double score;
        public String original_text;
        public String normalized_text;
        public Integer original_length;
        public Integer normalized_length;
    }
    
    // define Aggregate in SentimentAnalysisResponse
    public static class Aggregate {
        public String sentiment;
        public Double score;
    }
    
    // define document text input that is used in Add To Text Index request.
    // one Document represents one Case object.
    public static class Document {
        public String title;        // Case.Subject
        public String reference;    // Case.Id
        public String content;      // Case.Description + Case.Comments + Case.Emails + Case.Chatter
        // JSON.serialize produces 'null' string for null value, so use JSONGenerator to customize serialzation
        // IDOL custom fields are array, so they are serialized as array of string by JSONGenerator
        public String accountid;    // [Case.AccountId]
        public String accountname;  // [Case.AccountId.Name]
        public String contactid;        // [Case.ContactId]
        public String contactname;  // [Case.ContactId.Name]
        public String recordtypeid; // [Case.RecordTypeId]
        public String recordtypename;   // [Case.RecordTypeId.Name]
        public String type;         // [Case.Type]
        public String priority;     // [Case.Priority]
        public String status;           // [Case.Status]
        public String language;     // [Language identified by the Language Identification API call]
        public List<String> sentiment;        // [Sentiment identified by the Sentiment Analysis API call]
        public Date created_date;   // Case.CreatedDate
        public Date last_modified_date; // Case.LastModifiedDate
        // These are added for case search application
        public String casenumber;
        public String description;
    }
    
    // define Documents input used in Add to Text Index request
    public static class DocumentInput {
        public List<IDOL.Document> documents;
    }
    
    // define print options that's used in query request
    public enum Print {all, all_sections, fields, none, no_results, reference}  // unfortunately date, parametric are reserved
    // define highlight options that's used in query request
    public enum Highlight {off, sentences, summary_sentences, summary_terms}
    
    // define enum of FieldText operators
    public enum FieldTextOperator {MATCH, EXISTS, EMPTY, EQUAL, GREATER, LESS, NRANGE, NOTEQUAL, GTNOW, LTNOW, RANGE, BIAS, BIASDATE, BIASDISTCARTESIAN, BIASDISTPHERICAL}
    
    // define query response for case index that's returned in various query response 
    // custom fields are for case index
    public static class DocumentOutput {
        public String reference;    // optional
        public Double weight;       // optional
        public List<String> links;      // optional
        public String index;        // optional
        public String title;        // optional
        public String summary;      // optional
        public String content;  
        // custom fileds that were added in case indexing
        // all custom fields are returned as array
        public List<String> accountid;  // [Case.AccountId]
        public List<String> accountname;    // [Case.AccountId.Name]
        public List<String> contactid;      // [Case.ContactId]
        public List<String> contactname;    // [Case.ContactId.Name]
        public List<String> recordtypeid;   // [Case.RecordTypeId]
        public List<String> recordtypename; // [Case.RecordTypeId.Name]
        public List<String> type;           // [Case.Type]
        public List<String> priority;       // [Case.Priority]
        public List<String> status;         // [Case.Status]
        public List<String> language;       // [Language identified by the Language Identification API call]
        public List<String> sentiment;      // [Sentiment identified by the Sentiment Analysis API call]
        public List<Date> created_date; // Case.CreatedDate
        public List<Date> last_modified_date;   // Case.LastModifiedDate
        // These are added for case search application
        public List<String> casenumber;
        public List<String> description;
    }
    
    // define query response(Find Similar, Query Text Index) that returns a array of DocumentOutput
    public static class DocumentOutputs {
        public List<IDOL.DocumentOutput> documents;
    }
    
    // define entities object returned in Find Related Concepts search
    // Make it property so that VF can access fields
    public static class Entities {
        public String text;
        public Integer docs_with_phrase;
        public Integer occurrences;
        public Integer docs_with_all_terms;
        public Integer cluster;
    }
    
    // define response of Find Related Concepts Search
    public static class FindRelatedConceptsResponse {
        public List<IDOL.Entities> entities;
    }
}
